/* 
  Copyright (c) SilverLining 2015
  Date:    2016-1-7
  File:    shim_process.cpp  
  Description: 

*/

#include "stdafx.h"

using namespace System;
using namespace System::Security;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;

#include "shim_object.h"
#include "shim_process.h"
#include "Archiver.h"
#include "GameObject.h"
#include "TimerState.h"
#include "Message.h"
#include "Package.h"
#include "Process.h"

using namespace m;
using namespace m::alloc;

namespace SL
{
	namespace M
	{
		shim_process::shim_process()
			: _ProcessEntryCallback(nullptr),
			_HandleMessageCallback(nullptr)
		{
		}

		shim_process::~shim_process()
		{
			if (TypeName)
			{
				free(TypeName);
			}

			if (_hProcess)
			{
				GCHandle hProcess = GCHandle::FromIntPtr((IntPtr)_hProcess);
				hProcess.Free();
			}
		}

		void shim_process::set_process(Process ^ pThis)
		{
			assert(pThis != nullptr);
			if (pThis != nullptr)
			{
				GCHandle hProcess = GCHandle::Alloc(pThis, GCHandleType::Weak);
				_hProcess = ((IntPtr)hProcess).ToPointer();

				IntPtr ipPeGch = Marshal::GetFunctionPointerForDelegate(pThis->_ProcessEntryDelegate);
				_ProcessEntryCallback = static_cast<ProcessEntryCallback>(ipPeGch.ToPointer());

				IntPtr ipHmGch = Marshal::GetFunctionPointerForDelegate(pThis->_HandleMessageDelegate);
				_HandleMessageCallback = static_cast<HandleMessageCallback>(ipHmGch.ToPointer());

				pin_ptr<const wchar_t> typeNameChars = PtrToStringChars(pThis->GetType()->AssemblyQualifiedName);
				assign(TypeName, typeNameChars);
			}
		}

		Process ^ shim_process::get_process() const
		{
			if (_hProcess)
			{
				GCHandle hProcess = GCHandle::FromIntPtr((IntPtr)_hProcess);
				return safe_cast<Process^>(hProcess.Target);
			}
			return nullptr;
		}
		
		void * shim_process::operator new(size_t sz)
		{
			return ::operator new(sz, pool);
		}
		
		void shim_process::operator delete(void * ptr)
		{
			::operator delete(ptr, pool);
		}

		bool shim_process::next_message()
		{
			return process::next_message();
		}

		std::wstring shim_process::to_string() const
		{
			return object::to_string() + L"+" + TypeName;
		}

		void shim_process::process_entry()
		{
			_ProcessEntryCallback();
		}

		bool shim_process::handle_message(m::message * m)
		{
			return _HandleMessageCallback(m);
		}
	}
}